package lan.battletank.element;

import lan.battletank.R;
import lan.battletank.environment.EnvConst;
import lan.battletank.environment.Stage;
import lan.battletank.main.GameStatus;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;

public class ExplosionEntity extends BaseElement {

    private final int PERIOD = 2; // lasting period of every phase
    private final int ALL_PHASE = 17; // Explosion all phase to render
    private final int EXPLOSION_RADIUS = 50; // damage will based on the radius

    /** Explosion image to use. */
    private Bitmap[] mExplosionImages = new Bitmap[ALL_PHASE];

    /** The explosion phase. */
    private int mPhase;

    /** Counter of each explosion phase. */
    private int mPeriodCounter;

    /** Constructor, initial all parameters here. */
    public ExplosionEntity(Context context) {
        mContext = context;
        Resources res = mContext.getResources();

        for (int i = 0; i < ALL_PHASE; i++) {
            mExplosionImages[i] = BitmapFactory.decodeResource(res, R.drawable.explosion_01 + i);
        }
        width = mExplosionImages[0].getWidth();
        height = mExplosionImages[0].getHeight();
        halfWidth = width / 2;
        halfHeight = height / 2;

        // Initialize default value.
        initialize();
    }

    public void draw(Canvas c) {
        if (mPhase > 0) {
            c.drawBitmap(mExplosionImages[mPhase - 1], centerX - width / 2, centerY - height / 2, null);
        }
    }

    public void setExplosion(BaseBattleUnitElement attacker, BaseBulletElement bullet, BaseBattleUnitElement target, IndicatorEntity indicator) {
        if (mPhase == 0) {
            centerX = (int) bullet.centerX;
            centerY = (int) bullet.centerY;
            // caculate the damage due to the explosion
            if (!Stage.isFloorHit) {
	            if (target.isHit()) {
	                target.takeDamage(bullet.damage);
	                target.setHit(false);
	            } else {
	                if (centerY > target.centerY - target.halfHeight && centerY < target.centerY + target.halfHeight) {
	                    int absDistance = (int) Math.abs(centerX - target.centerX) - target.halfWidth;
	                    if (absDistance < EXPLOSION_RADIUS) {
	                        float damageFactor = 1 - (float) absDistance / (float) (target.halfWidth + EXPLOSION_RADIUS);
	                        target.takeDamage((int) (bullet.damage * damageFactor));
	                    }
	                } else if (centerX > target.centerX - target.halfWidth && centerX < target.centerX + target.halfWidth) {
	                    int absDistance = (int) Math.abs(centerY - target.centerY) - target.halfHeight;
	                    if (absDistance < EXPLOSION_RADIUS) {
	                        float damageFactor = 1 - (float) absDistance / (float) (target.halfHeight + EXPLOSION_RADIUS);
	                        target.takeDamage((int) (bullet.damage * damageFactor));
	                    }
	                }
	                // TODO: corner calculation
	            }
            }
            mPhase++;
        }
        if (mPeriodCounter > PERIOD) {
            if (mPhase < ALL_PHASE) {
                mPeriodCounter = 1;
                mPhase++;
            } else {
                // explosion end
            	Stage.isFloorHit = false;
                initialize();
                bullet.reset();
                attacker.actionEnd();
                indicator.clearFireIndicator();
                if (attacker.isPlayer) {
                	GameStatus.setBattleStatus(EnvConst.BATTLE_PLAYER_TURN_END, indicator);
                } else {
                	GameStatus.setBattleStatus(EnvConst.BATTLE_ENEMY_TURN_END, indicator);
                }
            }
        } else {
            mPeriodCounter++;
        }
    }

    private void initialize() {
        centerX = 0;
        centerY = 0;
        mPhase = 0;
        mPeriodCounter = 0;
    }
}
